package com.lincoln.framework.bean;

import com.lincoln.framework.common.WebUtils;
import com.lincoln.framework.entity.SysAuthorization;
import com.lincoln.framework.entity.SysMenu;
import com.lincoln.framework.entity.SysRole;
import com.lincoln.framework.service.SysMenuService;
import com.lincoln.framework.spring.SpringContextUtil;
import com.lincoln.framework.utils.ParameterChecker;
import com.lincoln.framework.utils.StringUtilsEx;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统管理员角色权限
 * 
 * @author zwm
 */
public class SysRoleRights implements Serializable {

	private int roleId;

	private List<SysMenu> firstMenuList = new ArrayList<SysMenu>();

	/**
	 * 菜单名称，现二级目录
	 */
	private Map<Integer, List<SysMenu>> childMenuList = new HashMap<Integer, List<SysMenu>>();

	/**
	 * 菜单功能
	 */
	private Map<Integer, ArrayList<Integer>> menuButtonRights = new HashMap<Integer, ArrayList<Integer>>();

	/**
	 * 菜单uri-id对应map
	 */
	private Map<String, Integer> menuUriIdMap = new HashMap<String, Integer>();
	
	private Map<String,Integer> multiMenuUriMap = new HashMap<String, Integer>();
	
	public SysRoleRights() {
	}

	public SysRoleRights(SysRole role) {
		this.setMenusRights(role);
	}

	public SysRoleRights(List<SysMenu> firstMenus) {
		List<Integer> rights = new ArrayList<Integer>();
		for (int i = 0; i < 20; i++) {
			rights.add(1);
		}
		for (SysMenu sysMenu : firstMenus) {
			firstMenuList.add(sysMenu);
			if(!ParameterChecker.isNullOrEmpty(sysMenu.getUri())) {
				menuButtonRights.put(sysMenu.getId(), (ArrayList<Integer>) rights);
				menuUriIdMap.put(getBaseUri(sysMenu.getUri()), sysMenu.getId());
			}
			Map<String,Map<String,Integer>> repeatMap = new HashMap<String,Map<String,Integer>>();
			for (SysMenu childMenu : sysMenu.getChildMenus()) {
				if(!StringUtilsEx.isNullOrEmpty(getBaseUri(childMenu.getUri()))) {
					if(repeatMap.containsKey(getBaseUri(childMenu.getUri()))) {
						Map<String,Integer> map = repeatMap.get(getBaseUri(childMenu.getUri()));
						String uri = map.keySet().iterator().next();
						multiMenuUriMap.put(uri, map.get(uri));
						multiMenuUriMap.put(childMenu.getUri(), childMenu.getId());
					} else {
						final SysMenu menu = childMenu;
						repeatMap.put(getBaseUri(childMenu.getUri()), new HashMap<String,Integer>(){{
							this.put(menu.getUri(), menu.getId());
						}});
					}
				}
				
				menuButtonRights.put(childMenu.getId(), (ArrayList<Integer>) rights);
				menuUriIdMap.put(getBaseUri(childMenu.getUri()), childMenu.getId());
			}
			childMenuList.put(sysMenu.getId(), sysMenu.getChildMenus());
		}
	}

	/**
	 * 角色权限初始化
	 * 
	 * @param role
	 *            void
	 */
	public void setMenusRights(SysRole role) {
		if (role != null) {
			this.roleId = role.getId();
			List<SysAuthorization> authorizations = role.getAuthorizations();
			if (authorizations != null && authorizations.size() > 0) {
				List<Integer> menuId = new ArrayList<Integer>();
				for (SysAuthorization sysAuthorization : authorizations) {
					SysMenu sysMenu = sysAuthorization.getSysMenu();

					List<Integer> menuRight = new ArrayList<Integer>();
					String[] rights = StringUtilsEx.trim(sysAuthorization.getButtonRights(), ",").split(",");
					for (String right : rights) {
						menuRight.add(Integer.valueOf(right));
					}
					menuButtonRights.put(sysMenu.getId(), (ArrayList<Integer>) menuRight);
					menuId.add(sysMenu.getId());
					if (sysMenu.getChildMenus() != null && sysMenu.getChildMenus().size() > 0) {
						this.firstMenuList.add(sysMenu);
					}
				}

				for (SysMenu menu : firstMenuList) {
					List<SysMenu> hasRightsChildMenu = new ArrayList<SysMenu>();
					List<SysMenu> childMenus = menu.getChildMenus();
					Map<String,Map<String,Integer>> repeatMap = new HashMap<String,Map<String,Integer>>();
					for (SysMenu childMenu : childMenus) {
						if (menuId.contains(childMenu.getId())) {
							
							if(!StringUtilsEx.isNullOrEmpty(getBaseUri(childMenu.getUri()))) {
								if(repeatMap.containsKey(getBaseUri(childMenu.getUri()))) {
									Map<String,Integer> map = repeatMap.get(getBaseUri(childMenu.getUri()));
									String uri = map.keySet().iterator().next();
									multiMenuUriMap.put(uri, map.get(uri));
									multiMenuUriMap.put(childMenu.getUri(), childMenu.getId());
								} else {
									final SysMenu tmpMenu = childMenu;
									repeatMap.put(getBaseUri(childMenu.getUri()), new HashMap<String,Integer>(){{
										this.put(tmpMenu.getUri(), tmpMenu.getId());
									}});
								}
							}
							
							hasRightsChildMenu.add(childMenu);
							// 设置菜单权限对应
							menuUriIdMap.put(getBaseUri(childMenu.getUri()), childMenu.getId());
						}
					}
					childMenuList.put(menu.getId(), hasRightsChildMenu);
				}
			}
		}
	}

	/**
	 * 校验功能权限
	 * 
	 * @return boolean
	 */
	public boolean checkFunctionRights(int menuId) {
		return childMenuList.get(menuId) != null;
	}

	/**
	 * 判断按钮是否有权限
	 */
	public boolean checkButtonRights(int buttonId) {
		return this.checkButtonRights((String) WebUtils.getRequest().getAttribute("sysRequestUri"), buttonId);
	}

	/**
	 * 校验是否与菜单功能
	 * 
	 * @param uri
	 *            菜单链接
	 * @param buttonId
	 *            菜单按钮编号
	 * @return boolean
	 */
	public boolean checkButtonRights(String uri, int buttonId) {
		Integer menuId = menuUriIdMap.get(getBaseUri(uri));
		if (menuId == null) {
			return false;
		}
		return checkButtonRights(menuId, buttonId);
	}

	/**
	 * 根据菜单id、按钮id判断用户权限
	 * 
	 * @param menuId
	 * @param buttonId
	 * @return
	 * boolean
	 */
	public boolean checkButtonRights(int menuId, int buttonId) {
		List<Integer> list = menuButtonRights.get(menuId);
		if (list == null || list.size() == 0) {
			return false;
		}
		return list.get(buttonId - 1) == null ? false : list.get(buttonId - 1).equals(1);
	}
	
	/**
	 * 校验是否有菜单权限
	 * 
	 * @param uri
	 *            菜单链接
	 * @return boolean
	 */
	public boolean checkMenuRights(String uri) {
		Integer menuId = menuUriIdMap.get(getBaseUri(uri));
		if (menuId == null) {
			return false;
		}
		List<Integer> list = menuButtonRights.get(menuId);
		if (list == null || list.size() == 0) {
			return false;
		}
		for (Integer buttonRights : list) {
			if (buttonRights == 1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取一级菜单菜单id，用于聚焦
	 * 
	 * @param uri
	 * @return Integer
	 */
	public Integer getMenuIdByUri(String uri) {
		SysMenuService sysMenuService = SpringContextUtil.getBean("sysMenuService");
		SysMenu sysMenu = sysMenuService.findMenuByUri(uri);
		if(sysMenu!=null){
			return sysMenu.getId();
		}
		if(multiMenuUriMap.containsKey(uri)) {
			return multiMenuUriMap.get(uri);
		}
		Integer menuId = menuUriIdMap.get(getBaseUri(uri));
		return menuId;
	}

	private String getBaseUri(String uri) {
		if (ParameterChecker.isNullOrEmpty(uri) || uri.indexOf("/") == -1) {
			return uri;
		}
		return uri.substring(0, uri.lastIndexOf("/"));
	}

	public int getRoleId() {
		return roleId;
	}

	public void setRoleId(int roleId) {
		this.roleId = roleId;
	}

	public List<SysMenu> getFirstMenuList() {
		return firstMenuList;
	}

	public void setFirstMenuList(List<SysMenu> firstMenuList) {
		this.firstMenuList = firstMenuList;
	}

	public Map<Integer, List<SysMenu>> getChildMenuList() {
		return childMenuList;
	}

	public void setChildMenuList(Map<Integer, List<SysMenu>> childMenuList) {
		this.childMenuList = childMenuList;
	}

	public Map<Integer, ArrayList<Integer>> getMenuButtonRights() {
		return menuButtonRights;
	}

	public void setMenuButtonRights(Map<Integer, ArrayList<Integer>> menuButtonRights) {
		this.menuButtonRights = menuButtonRights;
	}

	public Map<String, Integer> getMenuUriIdMap() {
		return menuUriIdMap;
	}

	public void setMenuUriIdMap(Map<String, Integer> menuUriIdMap) {
		this.menuUriIdMap = menuUriIdMap;
	}

}
